package com.ruoyi.cs.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.Response;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.SendSms;
import com.ruoyi.common.utils.pay.HttpsUtils;
import com.ruoyi.common.utils.pay.SignUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.common.yyyoupin.RSAUtils;
import com.ruoyi.common.yyyoupin.bean.CallBackInfoVo;
import com.ruoyi.common.yyyoupin.bean.CallbackInfo;
import com.ruoyi.common.yyyoupin.bean.OrderCancelReason;
import com.ruoyi.common.yyyoupin.bean.SaleResponse;
import com.ruoyi.cs.domain.*;
import com.ruoyi.cs.domain.vo.*;
import com.ruoyi.cs.mapper.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.cs.service.CommonService;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.service.ISysDictDataService;
import com.tencentcloudapi.cls.v20201016.models.CallBackInfo;
import com.tencentcloudapi.tci.v20190318.models.Face;
import org.apache.poi.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.cs.service.ITBackpackService;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import static java.io.File.separator;

/**
 * 背包信息Service业务层处理
 *
 * @author ruoyi
 * @date 2021-03-25
 */
@Service
@SuppressWarnings("all")
public class TBackpackServiceImpl implements ITBackpackService
{
    private static final Logger log = LoggerFactory.getLogger(TBackpackServiceImpl.class);

    @Autowired
    private TBackpackMapper tBackpackMapper;

    @Autowired
    private TUserMapper tUserMapper;

    @Autowired
    private TExchangeMapper tExchangeMapper;

    @Autowired
    private TGoodsMapper tGoodsMapper;

    @Autowired
    private TRechargeMapper tRechargeMapper;
    @Autowired
    private ISysDictDataService sysDictDataService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private CommonService commonService;
    @Autowired
    private TBackpackOperateMapper tBackpackOperateMapper;
    @Autowired
    private RedisLock redisLock;
    @Autowired
    private TBalanceChangeMapper balanceChangeMapper;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private TGoodsPoolMapper tGoodsPoolMapper;


    /**
     * 查询背包信息
     *
     * @param bbId 背包信息ID
     * @return 背包信息
     */
    @Override
    public TGoodsBackVo selectTBackpackById(String bbId)
    {
        TBackpack tBackpack = tBackpackMapper.selectTBackpackById(bbId);
        TGoods tGoods = tGoodsMapper.selectTGoodsById(tBackpack.getGoodsId());
        TUser tUser = tUserMapper.selectTUserById(tBackpack.getUserId());

        TGoodsBackVo tGoodsBackVo = new TGoodsBackVo();
        BeanUtils.copyProperties(tGoods,tGoodsBackVo);
        tGoodsBackVo.setBbStatus(tBackpack.getBbStatus());
        if (tUser != null) {
            tGoodsBackVo.setUserName(tUser.getUserName());
            tGoodsBackVo.setUserPhone(tUser.getUserPhone());
        }
        tGoodsBackVo.setUserId(tBackpack.getUserId());
        return tGoodsBackVo;
    }

    /**
     * 查询背包信息列表
     *
     * @param tBackpack 背包信息
     * @return 背包信息
     */
    @Override
    public List<TBackpack> selectTBackpackList(TBackpack tBackpack)
    {
        return tBackpackMapper.selectTBackpackList(tBackpack);
    }

    /**
     * 新增背包信息
     *
     * @param tBackpack 背包信息
     * @return 结果
     */
    @Override
    public int insertTBackpack(TBackpack tBackpack)
    {
        tBackpack.setCreateTime(DateUtils.getNowDate());
        return tBackpackMapper.insertTBackpack(tBackpack);
    }

    /**
     * 修改背包信息
     *
     * @param tBackpack 背包信息
     * @return 结果
     */
    @Override
    public Response updateTBackpack(TBackpack tBackpack)
    {
        /**还需要补充取货操作，暂时缺接口*/

        if (tBackpack.getBbStatus().equals(Constants.BBSTATUS2)) {
            /**判断饰品库存状态*/
            TGoods tGoods = tGoodsMapper.selectTGoodsById(tBackpack.getGoodsId());
            if (tGoods.getGoodsStockStatus().equals(Constants.STOCKSTATUS1)){
                return Response.fail(Constants.FAILCODE,"饰品库存不足，请联系管理员！");
            }
            /**用户信息*/
            TUser tUser = tUserMapper.selectTUserById(tBackpack.getUserId());
            if (tUser.getUserType().equals(Constants.USERTYPE1) || tUser.getUserType().equals(Constants.USERTYPE2)) {
                return Response.fail(Constants.FAILCODE,"主播和机器人不允许取货！");
            }
        }
        tBackpack.setUpdateTime(DateUtils.getNowDate());
        tBackpackMapper.updateTBackpack(tBackpack);
        return Response.success();
    }

    /**
     * 批量删除背包信息
     *
     * @param bbIds 需要删除的背包信息ID
     * @return 结果
     */
    @Override
    public int deleteTBackpackByIds(String[] bbIds)
    {
        return tBackpackMapper.updateTBackpackDelFlagBatch(Constants.DELETE,bbIds);
    }

    /**
     * 删除背包信息信息
     *
     * @param bbId 背包信息ID
     * @return 结果
     */
    @Override
    public int deleteTBackpackById(String bbId)
    {
        return tBackpackMapper.deleteTBackpackById(bbId);
    }

    /**
     * 轮播列表
     * @return
     */
    @Override
    public List<GoodsBelongingVo> carouselList(){
        String beginCreateTime = DateUtils.getDate() + " 00:00:00";
        List<GoodsBelongingVo> carouselList = tBackpackMapper.carouselList(beginCreateTime);
        return carouselList;
    }

    /**
     * 停用
     * @param bbIds
     * @return
     */
    @Override
    public int stopTbackpack(String[] bbIds) {
        return tBackpackMapper.updateTBackpackDelFlagBatch(Constants.FAIL,bbIds);
    }

    /**
     * 启用
     * @param bbIds
     * @return
     */
    @Override
    public int enableTbackpack(String[] bbIds) {
        return tBackpackMapper.updateTBackpackDelFlagBatch(Constants.SUCCESS,bbIds);
    }

    /**
     * 饰品兑换
     * @param userId 用户ID
     * @param bbIds 背包ID  多个ID用逗号拼接
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response exchangeGoogs(String userId,List<String> bbIds){
        if(CollectionUtil.isEmpty(bbIds)){
            return Response.fail(Constants.FAILCODE, "请选择兑换的饰品");
        }
        /**判断该用户是否存在*/
        TUser tUser = tUserMapper.selectTUserById(userId);
        if (StringUtils.isNull(tUser) || !Constants.SUCCESS.equals(tUser.getDelFlag())){
            return Response.fail(Constants.FAILCODE,"用户不存在或已被冻结，请联系客服");
        }

        /**根据背包ID 获取背包信息列表*/
        String[] bs =bbIds.toArray(new String[0]);
        List<TBackpack> backpackList = tBackpackMapper.selectTBackpackBatchByIds(bs,userId);
        if (backpackList.size() !=  bs.length) {
            return Response.fail(Constants.FAILCODE,"重复操作");
        }

        BigDecimal secondCurrencyBefore = tUser.getSecondCurrency();
        BigDecimal totalfee = backpackList.stream().map(TBackpack::getGoodsPrice).reduce(BigDecimal.ZERO,BigDecimal::add);
        BigDecimal secondCurrency = secondCurrencyBefore;
        List<TExchange> tExchangeList = new ArrayList<>();
        /**修改用户余额*/
        for (TBackpack bean:backpackList) {
            String lockKey = Constants.RETRIEVEKEY + bean.getBbId();
            String lockTime = DateUtils.getTimeAfter(DateUtils.getNowDate(), 1);
            lockTime = Long.toString(DateUtils.parseDate(lockTime).getTime());
            try {
                boolean lockflag = redisLock.lock(lockKey, lockTime);
                if (lockflag) {
                    bean.setAuditStatus(Constants.AUDITSTATUS5);
                    /**根据背包ID 修改背包信息状态*/
                    int statusrow = tBackpackMapper.updateTBackpackStatusBatch(bean);
                    if (statusrow == 0){
                        throw new CustomException("重复操作！");
                    }
                    /**插入兑换表*/
                    TExchange tExchange = new TExchange();
                    tExchange.setUserId(userId);
                    tExchange.setGoodsId(bean.getGoodsId());
                    tExchange.setGoodsExprice(bean.getGoodsPrice());
                    tExchange.setBbId(bean.getBbId());
                    tExchange.setDhBeforeBalance(secondCurrency);
                    tExchange.setCreateTime(DateUtils.getNowDate());
                    tExchange.setDelFlag(Constants.SUCCESS);
                    /**余额变动*/
                    secondCurrency = secondCurrency.add(bean.getGoodsPrice());
                    tExchange.setDhAfterBalance(secondCurrency);
                    tExchangeList.add(tExchange);
                }else {
                    throw new CustomException("请稍后再试！");
                }
            } finally {
                redisLock.release(lockKey, lockTime);
            }
        }
        /**插入兑换记录*/
        tExchangeMapper.insertTExchangeBatch(tExchangeList);

        tUser.setSecondCurrency(secondCurrency);
        tUser.setUpdateTime(DateUtils.getNowDate());
        int userrow = tUserMapper.updateTUserBalance(tUser);
        if (userrow == 0){
            throw new CustomException("网络延迟");
        }

        /**金额变动日志记录*/
        TBalanceChange balanceChange= new TBalanceChange();
        balanceChange.setUserId(userId);
        balanceChange.setBalanceBefore(tUser.getUserBalance());
        balanceChange.setOperationType(Constants.OPERATIONTYPE5);
        balanceChange.setFrequency(backpackList.size());
        balanceChange.setFee(totalfee);
        balanceChange.setCorrespondingid(StringUtils.join(bbIds.toArray(),","));
        balanceChange.setCreateTime(DateUtils.getNowDate());
        balanceChange.setBalanceAfter(tUser.getUserBalance());
        balanceChange.setSecondCurrencyBefore(secondCurrencyBefore);
        balanceChange.setSecondCurrencyAfter(secondCurrency);
        balanceChange.setCostFee(totalfee);
        balanceChange.setProfitPrice(totalfee);
        balanceChangeMapper.insertTBalanceChange(balanceChange);

        return Response.success();
    }

    /**
     * 获取我的背包信息
     * @param userId
     * @return
     */
    @Override
    public List<TBackpack> getMyTBackpack(TBackPackVo tBackpack){
        return tBackpackMapper.getMyTBackpack(tBackpack);
    }


    @Override
    public List<TBackpack> gameRecord(TBackPackVo tBackpack) {
        return tBackpackMapper.gameRecord(tBackpack);
    }

    /**
     * 后台用户背包信息
     * @param tBackPackVo
     * @return
     */
    @Override
    public List<TBackPackVo> tBackpackListBack(TBackPackVo tBackPackVo) {
        return tBackpackMapper.tBackpackListBack(tBackPackVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response confirmShipment(String bbId,String type) {
        if (StringUtils.isEmpty(bbId)) {
            return Response.fail("请选择需要操作的数据");
        }
        if (StringUtils.isEmpty(type)) {
            return Response.fail("请选择是否收货");
        }

        TBackpack tBackpack1 = tBackpackMapper.selectTBackpackById(bbId);
        if(tBackpack1 == null){
            return Response.fail("当前订单不存在，请核对后重试！");
        }
        if(tBackpack1.getBuyStatus().equals(Constants.SUCCESS)){
            return Response.fail("当前购买状态为正常，请联系管理员！");
        }
        if(!tBackpack1.getBbStatus().equals(Constants.BBSTATUS1)){
            return Response.fail("当前背包状态不为取回中，请联系管理员！");
        }
        String operateId = DateUtils.dateTimeNow()+ IdUtils.fastUUID().substring(0,10);
        TBackpack tBackpack = new TBackpack();
        TBackpackOperate tBackpackOperate = new TBackpackOperate();
        tBackpackOperate.setOperateId(operateId);
        tBackpackOperate.setBbId(bbId);
        tBackpackOperate.setRemark(tBackpack1.getOrderId());
        tBackpackOperate.setUserId(tBackpack1.getUserId());
        tBackpackOperate.setAuditStatus(tBackpack1.getAuditStatus());
        tBackpackOperate.setCreateTime(DateUtils.getNowDate());
        tBackpackOperate.setDelivery(tBackpack1.getDelivery());
        /*确认正常*/
        BigDecimal quotafee =BigDecimal.ZERO;
        if (Constants.SUCCESS.equals(type)) {
            tBackpack.setBbId(bbId);
            tBackpack.setBbStatus(Constants.BBSTATUS2);
            tBackpack.setBuyStatus(Constants.SUCCESS);
            tBackpack.setErrormsg("人工确认收货");
            tBackpack.setUpdateTime(DateUtils.getNowDate());

            tBackpackOperate.setOperateStatus(Constants.BBSTATUS2);
            tBackpackOperate.setMsg("管理员确认购买状态正常");
        } else {
            tBackpack.setBbId(bbId);
            tBackpack.setBbStatus(Constants.BBSTATUS0);
            tBackpack.setBuyStatus(Constants.SUCCESS);
            tBackpack.setErrormsg("");
            tBackpack.setUpdateTime(DateUtils.getNowDate());

            tBackpackOperate.setMsg("管理员确认购买状态异常");
            tBackpackOperate.setOperateStatus(Constants.BBSTATUS0);

            quotafee = quotafee.add(tBackpack.getGoodsPrice());
        }
        int i = tBackpackMapper.updateTBackpackerror(tBackpack);
        if (i > 0) {
            tBackpackOperateMapper.insertTBackpackOperate(tBackpackOperate);
            if(quotafee.compareTo(BigDecimal.ZERO) > 0){
                tUserMapper.subHistoryRecoveryQuota(tBackpack.getUserId(),quotafee);
            }
            return Response.success();
        }
        return Response.fail("操作失败");
    }

    /**
     * 人工审核
     * @param bbId
     * @param auditStatus
     * @return
     */
    @Override
    public Response audit(String bbId, String auditStatus,String delivery) {
        delivery = "2";//发货方式全为自动发货
        if (StringUtils.isEmpty(bbId) ||  StringUtils.isEmpty(auditStatus)) {
            return  Response.fail(Constants.FAILCODE,"参数不能为空！");
        }
        TBackPackVo tBackpack = tBackpackMapper.selectTBackpackByIdVo(bbId);
        if (!tBackpack.getAuditStatus().equals(Constants.AUDITSTATUS0)) {
            return  Response.fail(Constants.FAILCODE,"已完成审核操作无需重复进行！");
        }
        TUser user = tUserMapper.selectTUserById(tBackpack.getUserId());
        if (user == null || !Constants.SUCCESS.equals(user.getDelFlag())) {
            return Response.fail(Constants.FAILCODE, "用户不存在或已被冻结，请联系客服！");
        }
        if (StringUtils.isEmpty(user.getSteamID())) {
            return Response.fail(Constants.FAILCODE, "用户未绑定stream链接");
        }
        /**设置取回记录*/
        String operateId = DateUtils.dateTimeNow()+ IdUtils.fastUUID().substring(0,10);
        tBackpack.setOperateId(operateId);
        tBackpack.setDelivery(delivery);
        TBackpackOperate tBackpackOperate = new TBackpackOperate();
        tBackpackOperate.setOperateId(operateId);
        tBackpackOperate.setBbId(tBackpack.getBbId());
        tBackpackOperate.setOperateStatus(tBackpack.getBbStatus());
        tBackpackOperate.setUserId(tBackpack.getUserId());
        tBackpackOperate.setAuditStatus(auditStatus);
        tBackpackOperate.setCreateTime(DateUtils.getNowDate());
        tBackpackOperate.setDelivery(delivery);
        try {
            BigDecimal quofee = BigDecimal.ZERO;
            if (auditStatus.equals(Constants.AUDITSTATUS1)) {
                /**审核通过，发起快速购买接口*/
                try {
                    String res = commonService.auditAuickBuyYY(tBackpack);
                    JSONObject jsonObject = JSON.parseObject(res);
                    if (jsonObject.getInteger("code") != 0) {
                        /**发起购买失败*/
                        tBackpack.setBbStatus(Constants.BBSTATUS4);
                        tBackpack.setErrormsg(jsonObject.getString("msg"));
                        tBackpack.setRetrieveErrorTime(DateUtils.getNowDate());
                        tBackpackOperate.setOperateStatus(Constants.BBSTATUS4);
                        tBackpackOperate.setMsg(jsonObject.getString("msg"));
                    } else {
                        /**发起购买成功*/
                        tBackpack.setOrderId(jsonObject.getJSONObject("data").getString("orderNo"));
                        tBackpackOperate.setMsg("取回中");
                        tBackpackOperate.setRemark(jsonObject.getJSONObject("data").getString("orderNo"));
                    }
                } catch (Exception e) {
                    log.error("发起快速购买接口异常,订单号:{},异常信息：{}",tBackpack.getBbId(),e.getMessage());
                    tBackpack.setAuditStatus(Constants.AUDITSTATUS1);
                    tBackpack.setBbStatus(Constants.BBSTATUS1);
                    tBackpack.setBuyStatus(Constants.FAIL);

                    tBackpackOperate.setMsg("取回中");
                    tBackpackOperate.setRemark("人工审核通过后发起购买异常,默认已发起购买");
                }
            }else{
                tBackpack.setBbStatus(Constants.BBSTATUS0);
                tBackpack.setErrormsg("审核不通过，返还背包");
                tBackpack.setRetrieveErrorTime(DateUtils.getNowDate());

                tBackpackOperate.setOperateStatus(Constants.BBSTATUS0);
                tBackpackOperate.setMsg("审核不通过，返还背包");

                quofee = quofee.add(tBackpack.getGoodsPrice());
            }
            tBackpack.setAuditStatus(auditStatus);
            tBackpack.setAuditTime(DateUtils.getNowDate());
            tBackpackMapper.updateTBackpackVo(tBackpack);
            tBackpackOperateMapper.insertTBackpackOperate(tBackpackOperate);
            if(quofee.compareTo(BigDecimal.ZERO)>0){
                tUserMapper.subHistoryRecoveryQuota(tBackpack.getUserId(),quofee);
            }
            return Response.success();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("人工审核异常：{}",e.getMessage());
            return Response.fail(Constants.FAILCODE,"人工审核异常，请勿重复点击！");
        }

    }

    @Override
    public List<TBackpack> retrieveList(String userId,String goodsName) {
        return tBackpackMapper.retrieveList(userId,goodsName);
    }

    @Override
    public Map<String, BigDecimal> retrieveCount(String userPhone,String userName,String startTime,String endTime) {
        TRechargeVo tRechargeVo = new TRechargeVo();
        tRechargeVo.setUserPhone(userPhone);
        tRechargeVo.setUserName(userName);
        //Map<String,BigDecimal> map = tRechargeMapper.countTRechargeToday();
        Map<String,BigDecimal> map = tRechargeMapper.countTRechargeTodayByCondition(tRechargeVo);
        //Map<String,BigDecimal> map1 = tBackpackMapper.retrieveCountToday();
        Map<String,BigDecimal> map1 = tBackpackMapper.retrieveCountTodayByCondition(tRechargeVo);
        Map<String,BigDecimal> map2 = tBackpackMapper.retrieveCountTotalByCondition(userPhone,userName, startTime, endTime);
        map.putAll(map2);
        map.putAll(map1);
        map.put("profitMoneyTodal",map.get("czMoneyToday").subtract(map.get("retrieveMoneyToday")));
        return map;
    }

//    /**
//     * 批量取回(停用)
//     * @param bbStatus
//     * @param userId
//     * @return
//     */
//    @Override
//    public Response batchRetrieve(List<String> bbIds, String userId) {
//        if (bbIds.isEmpty()) {
//            return Response.fail(Constants.FAILCODE, "取回饰品不能为空！");
//        }
//        TUser user = tUserMapper.selectTUserById(userId);
//        if (user == null || !Constants.SUCCESS.equals(user.getDelFlag())) {
//            return Response.fail(Constants.FAILCODE, "用户不存在或已被冻结，请联系客服！");
//        }
//        if (StringUtils.isEmpty(user.getSteamID())) {
//            return Response.fail(Constants.FAILCODE, "请绑定steam交易链接再取回！");
//        }
//        if (user.getUserType().equals(Constants.USERTYPE1) && user.getIsRetrieve().equals("1")) {
//            return Response.fail(Constants.FAILCODE, "不满足取回条件！");
//        }
//        if (user.getUserTotalRecharge().compareTo(new BigDecimal(1)) < 0) {
//            return Response.fail(Constants.FAILCODE, "请先进行充值后再取货！");
//        }
//
//        String[] ids = bbIds.toArray(new String[0]);
//        List<TBackPackVo> tBackpackList = tBackpackMapper.selectTBackpackBatchByIdsVo(ids, userId);
//        if (tBackpackList.size() != ids.length) {
//            return Response.fail(Constants.FAILCODE, "重复操作，请刷新页面！");
//        }
//        /**单个用户每日最多取回饰品数量*/
//        String goodsNum = sysDictDataService.selectDictDataById(132L).getDictValue();
//        /**人工审核门槛*/
//        String auditThreshold = sysDictDataService.selectDictDataById(133L).getDictValue();
//        /**单日取回总金额上限*/
//        String moneyUpperlimit = sysDictDataService.selectDictDataById(134L).getDictValue();
//        /**获取单日取回总金额上限*/
//        String DRQHZJESXKEY = Constants.DRQHZJESXKEY;
//        BigDecimal feelimit = redisCache.getCacheObject(DRQHZJESXKEY) == null ? new BigDecimal(0) : redisCache.getCacheObject(DRQHZJESXKEY);
//        for (TBackpack tBackpack : tBackpackList) {
//            if (Constants.AUDITSTATUS4.equals(tBackpack.getAuditStatus())) {
//                return Response.fail(Constants.FAILCODE, "禁止取回饰品的饰品，只能兑换或者联系客服！");
//            }
//            feelimit = feelimit.add(tBackpack.getGoodsPrice());
//        }
//        String auditStatus = "0";
//        /**用户单日取回饰品数量的key*/
//        String key = Constants.KEY + userId;
//        Integer num = redisCache.getCacheObject(key) == null ? 0 : redisCache.getCacheObject(key);
//        int userNum = num + ids.length;
//        if (goodsNum != null && Integer.parseInt(goodsNum) > 0) {
//            if (Integer.parseInt(goodsNum) < userNum) {
//                return Response.fail(Constants.FAILCODE, "为了您的账号安全，请次日再取回！");
//            }
//        }
//        /**重新设值并设值过期时间*/
//        Calendar c = Calendar.getInstance();
//        c.setTime(new Date());
//        c.add(Calendar.DAY_OF_MONTH, 1);
//        String time = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime()) + " 00:00:00";
//        Long expiretime = DateUtils.getDatePoor1(DateUtils.parseDate(time), DateUtils.getNowDate());
//        redisCache.setCacheObject(key, userNum, new Long(expiretime).intValue(), TimeUnit.MINUTES);
//
//        /**判断单日取回总金额*/
//        if (moneyUpperlimit != null && Long.parseLong(moneyUpperlimit) > 0) {
//            if (new BigDecimal(moneyUpperlimit).compareTo(feelimit) < 0) {
//                return Response.fail(Constants.FAILCODE, "为了您的账号安全，请次日再取回！");
//            }
//        }
//        /**设置Redis中单日取回金额的*/
//        redisCache.setCacheObject(DRQHZJESXKEY, feelimit, new Long(expiretime).intValue(), TimeUnit.MINUTES);
//
//        if (auditThreshold != null && Double.parseDouble(auditThreshold) > 0) {
//            for (TBackpack tBackpack : tBackpackList) {
//                tBackpack.setBbStatus(Constants.BBSTATUS1);
//                tBackpack.setRetrieveTime(DateUtils.getNowDate());
//                if (tBackpack.getGoodsPrice().compareTo(new BigDecimal(auditThreshold)) >= 0) {
//                    tBackpack.setAuditStatus(Constants.AUDITSTATUS0);
//                    tBackpack.setErrormsg("正在审核中！");
//                } else {
//                    tBackpack.setAuditStatus(Constants.AUDITSTATUS2);
//                }
//            }
//        } else {
//            for (TBackpack tBackpack : tBackpackList) {
//                tBackpack.setBbStatus(Constants.BBSTATUS1);
//                tBackpack.setRetrieveTime(DateUtils.getNowDate());
//                tBackpack.setAuditStatus(Constants.AUDITSTATUS2);
//            }
//        }
//        /**需要补充快速购买接口*/
//        boolean flag = true;
//        /**取回记录*/
//        List<TBackpackOperate> tBackpackOperateList = new ArrayList<>();
//        for (TBackPackVo tBackPackVo : tBackpackList) {
//            /**插入取回记录*/
//            String operateId = DateUtils.dateTimeNow() + IdUtils.fastUUID().substring(0, 10);
//            tBackPackVo.setOperateId(operateId);
//            TBackpackOperate tBackpackOperate = new TBackpackOperate();
//            tBackpackOperate.setOperateId(operateId);
//            tBackpackOperate.setBbId(tBackPackVo.getBbId());
//            tBackpackOperate.setOperateStatus(tBackPackVo.getBbStatus());
//            tBackpackOperate.setUserId(tBackPackVo.getUserId());
//            tBackpackOperate.setAuditStatus(tBackPackVo.getAuditStatus());
//            tBackpackOperate.setCreateTime(DateUtils.getNowDate());
//
//            String lockKey = Constants.RETRIEVEKEY + tBackPackVo.getBbId();
//            String lockTime = DateUtils.getTimeAfter(DateUtils.getNowDate(), 1);
//            lockTime = Long.toString(DateUtils.parseDate(lockTime).getTime());
//
//            try {
//                boolean lockflag = redisLock.lock(lockKey, lockTime);
//                if (lockflag) {
//                    commonService.queryPrice(tBackPackVo);
//                    if (tBackPackVo.getAuditStatus().equals(Constants.AUDITSTATUS2)) {
//                        String res = commonService.quickBuy(tBackPackVo);
//                        log.info("批量取回饰品返回购买信息背包ID:{},返回数据:{}",tBackPackVo.getBbId(),res);
//                        JSONObject jsonObject = JSON.parseObject(res);
//                        if (!jsonObject.getBooleanValue("success")) {
//                            tBackPackVo.setBbStatus(Constants.BBSTATUS4);
//                            tBackPackVo.setErrormsg(jsonObject.getString("errorMsg"));
//                            tBackPackVo.setRetrieveErrorTime(DateUtils.getNowDate());
//                            flag = false;
//
//                            tBackpackOperate.setMsg(jsonObject.getString("errorMsg"));
//                            tBackpackOperate.setOperateStatus(Constants.BBSTATUS4);
//
//                        } else {
//                            tBackPackVo.setOrderId(jsonObject.getJSONObject("data").getString("orderId"));
//
//                            tBackpackOperate.setMsg("取回中");
//                            tBackpackOperate.setRemark(jsonObject.getJSONObject("data").getString("orderId"));
//                        }
//                    } else {
//                        tBackpackOperate.setMsg("等待审核中");
//                    }
//                    /**修改背包状态*/
//                    tBackpackMapper.updateTBackpackStatusVo(tBackPackVo);
//                } else {
//                    tBackpackOperate.setMsg("取回失败，重复操作");
//                    tBackpackOperate.setOperateStatus(Constants.BBSTATUS4);
//                    flag = false;
//                }
//            } finally {
//                redisLock.release(lockKey, lockTime);
//            }
//            tBackpackOperateList.add(tBackpackOperate);
//        }
//        /**修改背包状态*/
////        tBackpackMapper.updateTBackpackStatusBatchVo(tBackpackList);
//
//        /**插入取回记录 */
//        tBackpackOperateMapper.batchInsertTBackpackOperate(tBackpackOperateList);
//        if (!flag) {
//            if (bbIds.size() > 1) {
//                return Response.success("部分饰品取回失败，请刷新页面重试！");
//            } else {
//                return Response.success("饰品取回失败，请刷新页面重试！");
//            }
//        }
//        return Response.success("正在取回中，请登录steam进行取回操作");
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response batchRecaption(List<String> bbIds, String userId){
        if(CollectionUtil.isEmpty(bbIds)){
            return Response.fail(Constants.FAILCODE, "请选择取回的饰品");
        }

        TUser user = tUserMapper.selectTUserById(userId);
        if (user == null || !Constants.SUCCESS.equals(user.getDelFlag())) {
            return Response.fail(Constants.FAILCODE, "用户不存在或已被冻结，请联系客服！");
        }
        if (StringUtils.isEmpty(user.getSteamID())) {
            return Response.fail(Constants.FAILCODE, "请绑定steam交易链接再取回！");
        }

        String[] ids = bbIds.toArray(new String[0]);
        List<TBackPackVo> tBackpackList = tBackpackMapper.selectTBackpackBatchByIdsVo(ids, userId);
        if (tBackpackList.size() != ids.length) {
            return Response.fail(Constants.FAILCODE, "重复操作");
        }
        /**判断用户取回额度是否充足*/
        BigDecimal totalGoodsPrice = tBackpackList.stream()
                .map(TBackPackVo::getGoodsPrice) // 获取每个对象的goodsPrice属性
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        SysConfig gen_config = sysConfigMapper.checkConfigKeyUnique("general_user_retrieve_limit_parameters");
        String general_user_retrieve_limit_parameters_val = gen_config == null ? "1" : gen_config.getConfigValue();

        BigDecimal totalCzf = user.getUserTotalRecharge().multiply(new BigDecimal(general_user_retrieve_limit_parameters_val)).setScale(2,BigDecimal.ROUND_HALF_UP);
        totalCzf = totalCzf.add(user.getExtraQuota());
        totalCzf = totalCzf.subtract(user.getHistoryRecoveryQuota());
        if(totalCzf.compareTo(totalGoodsPrice) < 0){
            return Response.fail(Constants.FAILCODE,"取回达上限，请加群联系客服处理，客服上班时间为：10:00~22:00，其余时间请留言客服耐心等待");
        }

        /**频道商户余额是否充足*/
        BigDecimal businessBalance = commonService.getAssetsInfo();
        if(businessBalance != null && businessBalance.compareTo(totalGoodsPrice) < 0){
            return Response.fail(Constants.FAILCODE,"网络波动，请加群联系客服");
        }

        if (user.getUserType().equals(Constants.USERTYPE1) && !"0".equals(user.getIsRetrieve())) {
            /*主播取回方法*/
            return zbBatchRecaption(tBackpackList, user);
        }
        /**赠送饰品类型的可以无条件取货*/
        boolean givefalg = true;
        for (TBackPackVo tBackpack : tBackpackList) {
            /**判断，如果是赠送饰品，可以无条件取货，存在其他类型的都不能直接取货*/
            if (!tBackpack.getGoodsBelongingType().equals(Constants.GOOGSBLTYPE7)){
                givefalg = false;
            }
        }

        if (Constants.USERTYPE0.equals(user.getUserType()) && !givefalg) {
            SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("picking_threshold");
            BigDecimal thresholdMoney = new BigDecimal(sysConfig.getConfigValue());
            if (user.getUserTotalRecharge().compareTo(thresholdMoney) < 0){
                return Response.fail(Constants.FAILCODE,"未防止恶意注册，累计充值"+thresholdMoney.intValue()+"金币即可进行取货！");
            }
        }

        /**单个用户每日最多取回饰品数量*/
        String goodsNum = sysDictDataService.selectDictDataById(132L).getDictValue();
        /**人工审核门槛*/
        String auditThreshold = sysDictDataService.selectDictDataById(133L).getDictValue();
        /**单日取回总金额上限*/
        String moneyUpperlimit = sysDictDataService.selectDictDataById(134L).getDictValue();

        /**获取单日取回总金额上限*/
        String DRQHZJESXKEY = Constants.DRQHZJESXKEY;
        BigDecimal feelimit = redisCache.getCacheObject(DRQHZJESXKEY) == null ? new BigDecimal(0) : redisCache.getCacheObject(DRQHZJESXKEY);
        /*获取单人当日取回总金额*/
        String drdrkey = Constants.DRDRKEY + userId;
        BigDecimal drdrje = redisCache.getCacheObject(drdrkey) == null ? new BigDecimal(0) : redisCache.getCacheObject(drdrkey);
        for (TBackPackVo tBackpack : tBackpackList) {
            if(user.getUserType().equals(Constants.USERTYPE1)){
                tBackpack.setProhibitRetrieve(Constants.FAIL);
            }
            if (Constants.AUDITSTATUS4.equals(tBackpack.getAuditStatus())) {
                return Response.fail(Constants.FAILCODE, "禁止取回饰品，请联系客服！");
            }
            if(!"0".equals(tBackpack.getGoodsType())){
                return Response.fail(Constants.FAILCODE, "非商品不能取回！");
            }
            feelimit = feelimit.add(tBackpack.getGoodsPrice());
            drdrje = drdrje.add(tBackpack.getGoodsPrice());
        }
        List<Integer> templateIds = tBackpackList.stream().map(TBackPackVo::getZBT).map(Integer::parseInt).distinct().collect(Collectors.toList());
        List<SaleResponse> saleResponseList = commonService.priceInfoYY(templateIds);
        for (Integer templateId : templateIds) {
            long count = saleResponseList.stream().filter(saleResponse -> saleResponse.getSaleTemplateResponse().getTemplateId().equals(templateId) && saleResponse.getSaleCommodityResponse().getSellNum()>0).count();
            if(count == 0){
                return Response.fail(Constants.FAILCODE, "当前存在无库存的饰品！");
            }
        }
        /**获取过期时间*/
        Long expiretime = getRedisExpiretime();
        /**用户单日取回饰品数量的key*/
        String key = Constants.KEY + userId;
        Integer num = redisCache.getCacheObject(key) == null ? 0 : redisCache.getCacheObject(key);
        int userNum = num + ids.length;
        if (goodsNum != null && Integer.parseInt(goodsNum) > 0) {
            if (Integer.parseInt(goodsNum) < userNum) {
                return Response.fail(Constants.FAILCODE, "为了您的账号安全，请次日再取回！");
            }
        }
        /**设置redis中单人当日取回数量*/
        redisCache.setCacheObject(key, userNum, new Long(expiretime).intValue(), TimeUnit.MINUTES);

        /**判断单日取回总金额*/
        if (moneyUpperlimit != null && Long.parseLong(moneyUpperlimit) > 0) {
            if (new BigDecimal(moneyUpperlimit).compareTo(feelimit) < 0) {
                return Response.fail(Constants.FAILCODE, "为了您的账号安全，请次日再取回！");
            }
        }
        /**设置Redis中单日取回金额的*/
        redisCache.setCacheObject(DRQHZJESXKEY, feelimit, new Long(expiretime).intValue(), TimeUnit.MINUTES);

        /**判断单人当日取回总金额上限*/
        SysConfig drdrqhzjesxConfig = sysConfigMapper.checkConfigKeyUnique("drdrqhzjesx");
        String drdrqhzjesx = drdrqhzjesxConfig == null || StringUtils.isEmpty(drdrqhzjesxConfig.getConfigValue()) ? "5000" : drdrqhzjesxConfig.getConfigValue();
        if (drdrqhzjesx != null && Long.parseLong(drdrqhzjesx) > 0) {
            if (new BigDecimal(drdrqhzjesx).compareTo(drdrje) < 0) {
                return Response.fail(Constants.FAILCODE, "为了您的账号安全，请次日再取回！");
            }
        }
        redisCache.setCacheObject(drdrkey, drdrje, new Long(expiretime).intValue(), TimeUnit.MINUTES);

        /*判断当日总取回上限*/
        SysConfig drqhzslsxConfig = sysConfigMapper.checkConfigKeyUnique("drqhzslsx");
        String drqhzslsx = drqhzslsxConfig == null || StringUtils.isEmpty(drqhzslsxConfig.getConfigValue()) ? "100" : drqhzslsxConfig.getConfigValue();
        String DRQHZSLSXKEY = Constants.DRQHZSLSXKEY;
        Integer oldTodayTotalNum = redisCache.getCacheObject(DRQHZSLSXKEY) == null ? 0 : redisCache.getCacheObject(DRQHZSLSXKEY);
        int todayTotalNum = oldTodayTotalNum + ids.length;
        if (drqhzslsx != null && Integer.parseInt(drqhzslsx) > 0) {
            if (Integer.parseInt(drqhzslsx) < todayTotalNum) {
                return Response.fail(Constants.FAILCODE, "为了您的账号安全，请次日再取回！");
            }
        }
        redisCache.setCacheObject(DRQHZSLSXKEY, todayTotalNum, new Long(expiretime).intValue(), TimeUnit.MINUTES);

        /**人工审核门槛*/
        tBackpackList.forEach(tBackpack -> {
            tBackpack.setBbStatus(Constants.BBSTATUS1);
            tBackpack.setDelivery(Constants.DELIVERY2);
            tBackpack.setRetrieveTime(DateUtils.getNowDate());
            if (auditThreshold != null && tBackpack.getGoodsPrice().compareTo(new BigDecimal(auditThreshold)) >= 0) {
                tBackpack.setAuditStatus(Constants.AUDITSTATUS0);
                tBackpack.setErrormsg("正在审核中！");
            } else {
                tBackpack.setAuditStatus(Constants.AUDITSTATUS2);
            }
        });

        BigDecimal quotafee = tBackpackList.stream().map(TBackPackVo::getGoodsPrice).reduce(BigDecimal.ZERO,BigDecimal::add);
        if(quotafee.compareTo(BigDecimal.ZERO) > 0){
            /**用户新增历史取回额度*/
            tUserMapper.addHistoryRecoveryQuota(userId,quotafee);
        }
        /**获取锁状态，更新背包状态，同时插入取回记录*/
        List<TBackpackOperate> tBackpackOperateList = new ArrayList<>();
        tBackpackList.forEach(tBackPackVo -> {
            String lockKey = Constants.RETRIEVEKEY + tBackPackVo.getBbId();
            String lockTime = DateUtils.getTimeAfter(DateUtils.getNowDate(), 1);
            lockTime = Long.toString(DateUtils.parseDate(lockTime).getTime());
            try {
                boolean lockflag = redisLock.lock(lockKey, lockTime);
                if (lockflag) {
                    /**获取饰品价格，判断是否需要人工审核*/
                    commonService.queryPriceYY(tBackPackVo);

                    /**插入取回记录*/
                    String operateId = DateUtils.dateTimeNow() + IdUtils.fastUUID().substring(0, 10);
                    TBackpackOperate tBackpackOperate = new TBackpackOperate();
                    tBackpackOperate.setOperateId(operateId);
                    tBackpackOperate.setBbId(tBackPackVo.getBbId());
                    tBackpackOperate.setOperateStatus(tBackPackVo.getBbStatus());
                    tBackpackOperate.setUserId(tBackPackVo.getUserId());
                    tBackpackOperate.setAuditStatus(tBackPackVo.getAuditStatus());
                    tBackpackOperate.setCreateTime(DateUtils.getNowDate());
                    tBackpackOperate.setMsg(tBackPackVo.getAuditStatus().equals(Constants.AUDITSTATUS0) ? "等待审核中" : "待购买阶段");
                    tBackpackOperate.setDelivery(tBackPackVo.getDelivery());
                    tBackpackOperateList.add(tBackpackOperate);

                    /**根修改背包信息状态*/
                    tBackPackVo.setIsCreateOrder(false);
                    int statusrow = tBackpackMapper.updateTBackpackStatusVo(tBackPackVo);
                    if (statusrow == 0){
                        throw new CustomException("商品信息变更，请稍后再试！");
                    }
                }else {
                    throw new CustomException("请稍后重试");
                }
            }finally {
                redisLock.release(lockKey, lockTime);
            }
        });
        /**插入取回记录信息*/
        tBackpackOperateMapper.batchInsertTBackpackOperate(tBackpackOperateList);
        /**饰品购买接口*/
        List<TBackPackVo> quickBackpackList = tBackpackList.stream().filter(bean -> bean.getAuditStatus().equals(Constants.AUDITSTATUS2)).collect(Collectors.toList());
        quickBuy(quickBackpackList);
        return Response.success("正在取回中");
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void quickBuy(List<TBackPackVo> tBackpackList){
        try {
            List<TBackpackOperate> tBackpackOperateList = new ArrayList<>();
            tBackpackList.forEach(tBackPackVo -> {
                /**插入取回记录*/
                String operateId = DateUtils.dateTimeNow() + IdUtils.fastUUID().substring(0, 10);
                TBackpackOperate tBackpackOperate = new TBackpackOperate();
                tBackpackOperate.setOperateId(operateId);
                tBackpackOperate.setBbId(tBackPackVo.getBbId());
                tBackpackOperate.setOperateStatus(tBackPackVo.getBbStatus());
                tBackpackOperate.setUserId(tBackPackVo.getUserId());
                tBackpackOperate.setAuditStatus(tBackPackVo.getAuditStatus());
                tBackpackOperate.setCreateTime(DateUtils.getNowDate());

                tBackPackVo.setOperateId(operateId);
                tBackPackVo.setIsCreateOrder(true);
                try {
                    String res = commonService.quickBuyYY(tBackPackVo);
                    if(res != null){
                        JSONObject jsonObject = JSON.parseObject(res);
                        if (jsonObject.getInteger("code") != 0) {
                            tBackPackVo.setBbStatus(Constants.BBSTATUS4);
                            tBackPackVo.setErrormsg(jsonObject.getString("msg"));
                            tBackPackVo.setRetrieveErrorTime(DateUtils.getNowDate());

                            tBackpackOperate.setMsg(jsonObject.getString("msg"));
                            tBackpackOperate.setOperateStatus(Constants.BBSTATUS4);
                        } else {
                            tBackPackVo.setErrormsg("");
                            tBackPackVo.setOrderId(jsonObject.getJSONObject("data").getString("orderNo"));

                            tBackpackOperate.setMsg("取回中");
                            tBackpackOperate.setRemark(jsonObject.getJSONObject("data").getString("orderNo"));
                        }
                    }else {
                        tBackPackVo.setErrormsg("");
                        tBackPackVo.setBbStatus(Constants.BBSTATUS1);
                        tBackPackVo.setBuyStatus(Constants.FAIL);

                        tBackpackOperate.setMsg("取回中");
                        tBackpackOperate.setRemark("购买接口响应异常，默认已发起购买");
                    }
                } catch (Exception e) {
                    log.error("取回购买饰品接口异常:{}",e);

                    tBackPackVo.setBbStatus(Constants.BBSTATUS1);
                    tBackPackVo.setBuyStatus(Constants.FAIL);
                    tBackPackVo.setErrormsg("");

                    tBackpackOperate.setMsg("取回中");
                    tBackpackOperate.setRemark("购买接口响应异常，默认已发起购买");
                }
                /**插入取回记录*/
                tBackpackOperateList.add(tBackpackOperate);
            });
            /**更新背包信息*/
            tBackpackMapper.updateBatchTBackpackStatusV2(tBackpackList);
            /**插入取回记录信息*/
            tBackpackOperateMapper.batchInsertTBackpackOperate(tBackpackOperateList);
        } catch (Exception e) {
            List<String> bbids = tBackpackList.stream().map(TBackPackVo::getBbId).collect(Collectors.toList());
            log.error("饰品取回调用购买接口阶段异常；{},背包ID:{}",e,JSON.toJSONString(bbids));
        }
    }


    public Long getRedisExpiretime(){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DAY_OF_MONTH, 1);
        String time = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime()) + " 00:00:00";
        Long expiretime = DateUtils.getDatePoor1(DateUtils.parseDate(time), DateUtils.getNowDate());
        return expiretime;
    }

    /**
     * 饰品购买的回执方法
     * @return
     */
    @Override
        public String buyNotify(NotifyBuyVo notifyBuyVo) {
        try {
            log.info("调用回执函数开始：参数:{}",notifyBuyVo.toString());
            String operateId = notifyBuyVo.getOutTradeNo();
            Map map = new HashMap();
            map.put("orderId",notifyBuyVo.getOrderId());
            map.put("status",notifyBuyVo.getStatus());
            map.put("statusName",notifyBuyVo.getStatusName());
            map.put("tradeOfferId",notifyBuyVo.getTradeOfferId());
            map.put("offerId",notifyBuyVo.getOfferId());
            map.put("outTradeNo",notifyBuyVo.getOutTradeNo());
            map.put("type",notifyBuyVo.getType());
            map.put("typeName",notifyBuyVo.getTypeName());
            map.put("createTime",notifyBuyVo.getCreateTime());
            map.put("payMoney",notifyBuyVo.getPayMoney());
            StringBuilder sb = new StringBuilder();
            sb.append("app-key=");
            sb.append(Constants.APP_KEY);
            sb.append("&language=zh_CN");
            String  result = HttpsUtils.sendGet("https://app.zbt.com/open/development/info",sb.toString(),null);
            log.info("ZBT回执函数调用获取用户开发者账号相关信息响应:{}",result);
            JSONObject jsonObject = JSON.parseObject(result);
            String sign = null;
            if (jsonObject.getBooleanValue("success")){
                sign = jsonObject.getJSONObject("data").getString("appSecret");
            }else{
                log.error("获取appSc异常:{}",jsonObject.getString("errorMsg"));
            }
            log.info("获取到的appSecret:{}",sign);
            String code = SignUtils.signGoods(map,sign);
            if (!notifyBuyVo.getSign().equals(code)) {
                log.error("饰品购买回执函数，验签失败:{}",code);
                return "failure";
            }
            TBackpackOperate operate = tBackpackOperateMapper.selectTBackpackOperateById(operateId);

            TBackpack tBackpack = tBackpackMapper.selectTBackpackById(operate.getBbId());

            TBackpackOperate tBackpackOperate = new TBackpackOperate();
            String operateId1 = DateUtils.dateTimeNow()+ IdUtils.fastUUID().substring(0,10);
            tBackpackOperate.setOperateId(operateId1);
            tBackpackOperate.setBbId(tBackpack.getBbId());
            tBackpackOperate.setUserId(tBackpack.getUserId());
            tBackpackOperate.setAuditStatus(tBackpack.getAuditStatus());
            tBackpackOperate.setRemark(notifyBuyVo.getOrderId());
            tBackpackOperate.setCreateTime(DateUtils.getNowDate());
            tBackpackOperate.setDelivery(tBackpack.getDelivery());
            if (notifyBuyVo.getStatus().equals("1")) {
                tBackpack.setBbStatus(Constants.BBSTATUS5);
                tBackpack.setUpdateTime(DateUtils.getNowDate());
                tBackpack.setErrormsg("等待发货！");
                tBackpackMapper.updateTBackpackerror(tBackpack);

                /**插入背包记录*/
                tBackpackOperate.setOperateStatus(Constants.BBSTATUS5);
                tBackpackOperate.setMsg("待发货");
                tBackpackOperateMapper.insertTBackpackOperate(tBackpackOperate);
            }else if (notifyBuyVo.getStatus().equals("3")) {
                tBackpack.setBbStatus(Constants.BBSTATUS6);
                tBackpack.setUpdateTime(DateUtils.getNowDate());
                tBackpack.setErrormsg("请尽快前往steam完成交易，超过20分钟将会取消交易！");
                tBackpackMapper.updateTBackpackerror(tBackpack);
                tBackpackOperate.setMsg("待收货");
                tBackpackOperate.setOperateStatus(Constants.BBSTATUS6);
                tBackpackOperateMapper.insertTBackpackOperate(tBackpackOperate);

                /**发送饰品收货短信提醒*/
                TUser tUser = tUserMapper.selectTUserById(tBackpack.getUserId());
                SendSms.sendDeliverGoodsCode(tUser.getUserPhone(),tBackpack.getBbGoodsName());
            }else if (notifyBuyVo.getStatus().equals("10")) {
                tBackpack.setBbStatus(Constants.BBSTATUS2);
                tBackpack.setArrivalTime(DateUtils.getNowDate());
                tBackpack.setUpdateTime(DateUtils.getNowDate());
                tBackpack.setErrormsg("已完成交易");
                tBackpack.setBuyStatus(Constants.SUCCESS);
                tBackpackMapper.updateTBackpackerror(tBackpack);

                tBackpackOperate.setMsg("完成交易");
                tBackpackOperate.setOperateStatus(Constants.BBSTATUS2);
                tBackpackOperateMapper.insertTBackpackOperate(tBackpackOperate);
            }else if (notifyBuyVo.getStatus().equals("11")) {
                tBackpack.setBbStatus(Constants.BBSTATUS4);
                tBackpack.setUpdateTime(DateUtils.getNowDate());
                tBackpack.setRetrieveErrorTime(DateUtils.getNowDate());
                tBackpack.setErrormsg("饰品将在20分钟后回到背包！");
                tBackpack.setBuyStatus(Constants.SUCCESS);
                tBackpackMapper.updateTBackpackerror(tBackpack);

                tBackpackOperate.setMsg("交易失败");
                tBackpackOperate.setOperateStatus(Constants.BBSTATUS4);
                tBackpackOperateMapper.insertTBackpackOperate(tBackpackOperate);
            }
            log.info("调用回执函数结束");
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
           log.error("饰品交易回执函数异常：{},异常数据:{}",e.getMessage(),JSON.toJSONString(notifyBuyVo));
            return "success";
        }
    }

    @Override
    public JSONObject buyNotify(CallBackInfoVo callBackInfoVo) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code",200);
        jsonObject.put("msg","成功");
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("messageNo",callBackInfoVo.getMessageNo());

        String messageNo = callBackInfoVo.getMessageNo();
        String backinfo = callBackInfoVo.getCallBackInfo();
        /**验签*/
        Map<String, Object> params = new HashMap<>();
        params.put("messageNo",messageNo);
        params.put("callBackInfo",backinfo);

        // 第一步：检查参数是否已经排序
        String[] keys = params.keySet().toArray(new String[0]);
        Arrays.sort(keys);
        // 第二步：把所有参数名和参数值串在一起
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : keys) {
            Object value = params.get(key);
            if (!org.springframework.util.StringUtils.isEmpty(value)) {
                stringBuilder.append(key).append(value);
            }
        }
        log.info("stringBuilder:{}",stringBuilder);
        //验证签名 RSAUtils.verifyByPublicKey参考 《RSA公私钥生成、签名》地址：https://www.yuque.com/yyyoupin/ckahux/wa9oz9z5fu67wvun
        boolean flag = false;
        try {
            flag = RSAUtils.verifyByPublicKey(stringBuilder.toString().getBytes(), RSAUtils.callback_public, callBackInfoVo.getSign());
        } catch (Exception e) {
           log.error("悠悠有品交易验签异常：{}",e.getMessage());
        }
        log.info("验签是否成功:{}",flag);
        if(flag){
            CallbackInfo callBackInfo = JSON.parseObject(backinfo,CallbackInfo.class);
            String operateId = callBackInfo.getMerchantOrderNo();
            String orderId =  callBackInfo.getOrderNo();
            Integer orderStatus = callBackInfo.getOrderStatus();
            Integer orderSubStatus = callBackInfo.getOrderSubStatus();

            TBackpackOperate operate = tBackpackOperateMapper.selectTBackpackOperateById(operateId);

            TBackpack tBackpack = tBackpackMapper.selectTBackpackById(operate.getBbId());
            /**设置订单号*/
            if(StringUtils.isNotEmpty(tBackpack.getOrderId())){
                tBackpack.setOrderId(orderId);
            }
            TBackpackOperate tBackpackOperate = new TBackpackOperate();
            String operateId1 = DateUtils.dateTimeNow()+ IdUtils.fastUUID().substring(0,10);
            tBackpackOperate.setOperateId(operateId1);
            tBackpackOperate.setBbId(tBackpack.getBbId());
            tBackpackOperate.setUserId(tBackpack.getUserId());
            tBackpackOperate.setAuditStatus(tBackpack.getAuditStatus());
            tBackpackOperate.setRemark(orderId);
            tBackpackOperate.setCreateTime(DateUtils.getNowDate());
            tBackpackOperate.setDelivery(tBackpack.getDelivery());
            if (orderStatus == 140 && orderSubStatus == 1101) {
                tBackpack.setBbStatus(Constants.BBSTATUS5);
                tBackpack.setUpdateTime(DateUtils.getNowDate());
                tBackpack.setErrormsg("待发送报价！");
                tBackpackMapper.updateTBackpackerror(tBackpack);

                /**插入背包记录*/
                tBackpackOperate.setOperateStatus(Constants.BBSTATUS5);
                tBackpackOperate.setMsg("待发送报价");
                tBackpackOperateMapper.insertTBackpackOperate(tBackpackOperate);
            }else if (orderStatus == 140 && orderSubStatus == 1103) {
                tBackpack.setBbStatus(Constants.BBSTATUS6);
                tBackpack.setUpdateTime(DateUtils.getNowDate());
                tBackpack.setErrormsg("请尽快前往steam完成交易，超过20分钟将会取消交易！");
                tBackpackMapper.updateTBackpackerror(tBackpack);
                tBackpackOperate.setMsg("待确认报价");
                tBackpackOperate.setOperateStatus(Constants.BBSTATUS6);
                tBackpackOperateMapper.insertTBackpackOperate(tBackpackOperate);

                /**发送饰品收货短信提醒*/
                TUser tUser = tUserMapper.selectTUserById(tBackpack.getUserId());
                SendSms.sendDeliverGoodsCode(tUser.getUserPhone(),tBackpack.getBbGoodsName());
            }else if (orderStatus == 340) {
                tBackpack.setBbStatus(Constants.BBSTATUS2);
                tBackpack.setArrivalTime(DateUtils.getNowDate());
                tBackpack.setUpdateTime(DateUtils.getNowDate());
                tBackpack.setErrormsg("已完成交易");
                tBackpack.setBuyStatus(Constants.SUCCESS);
                tBackpackMapper.updateTBackpackerror(tBackpack);

                tBackpackOperate.setMsg("完成交易");
                tBackpackOperate.setOperateStatus(Constants.BBSTATUS2);
                tBackpackOperateMapper.insertTBackpackOperate(tBackpackOperate);
            }else if (orderStatus == 280) {
                String failMsg = callBackInfo.getFailMsg();
                tBackpack.setBbStatus(Constants.BBSTATUS4);
                tBackpack.setUpdateTime(DateUtils.getNowDate());
                tBackpack.setRetrieveErrorTime(DateUtils.getNowDate());
//                tBackpack.setErrormsg("饰品将在20分钟后回到背包！");
                tBackpack.setErrormsg(StringUtils.isEmpty(failMsg) ? OrderCancelReason.getMessageByCode(orderSubStatus) : failMsg);
                tBackpack.setBuyStatus(Constants.SUCCESS);
                tBackpackMapper.updateTBackpackerror(tBackpack);

                tBackpackOperate.setMsg(StringUtils.isEmpty(failMsg) ? OrderCancelReason.getMessageByCode(orderSubStatus) : failMsg);
                tBackpackOperate.setOperateStatus(Constants.BBSTATUS4);
                tBackpackOperateMapper.insertTBackpackOperate(tBackpackOperate);
            }
            log.info("调用回执函数结束");
            resultMap.put("flag",true);
            jsonObject.put("data",resultMap);
            return jsonObject;

        }else {
            jsonObject.put("msg","验签失败");
            resultMap.put("flag",false);
            jsonObject.put("data",resultMap);
            return jsonObject;
        }
    }

    @Override
    public Long openBoxTotal() {
        return tBackpackMapper.openBoxTotal();
    }


    @Override
    public List<TBackpackOpenBoxTopFortyVo> backPackopenBoxTopForty(String goodsBelongingId) {
        return tBackpackMapper.backPackopenBoxTopForty(goodsBelongingId);
    }

    @Override
    public BigDecimal selectUrchaseQuota(String userId) {
        return tBackpackMapper.selectUrchaseQuota(userId);
    }

    /**
     * 主播取回方法
     * @param bbIds
     * @param userId
     * @return
     */
    private Response zbBatchRecaption(List<TBackPackVo> tBackpackList, TUser user) {
        if (tBackpackList.size() > 0) {
//            List<TBackpackOperate> tBackpackOperateList = new ArrayList<>();
            for (TBackpack tBackpack : tBackpackList) {
                tBackpack.setBbStatus(Constants.BBSTATUS1);
                tBackpack.setRetrieveTime(DateUtils.getNowDate());
                tBackpack.setAuditStatus(Constants.AUDITSTATUS2);
                tBackpack.setProhibitRetrieve(Constants.SUCCESS);
                tBackpack.setErrormsg("主播被禁止时取回操作");
                /**插入取回记录*/
//                String operateId = DateUtils.dateTimeNow() + IdUtils.fastUUID().substring(0, 10);
//                tBackpack.setOperateId(operateId);
//                TBackpackOperate tBackpackOperate = new TBackpackOperate();
//                tBackpackOperate.setOperateId(operateId);
//                tBackpackOperate.setBbId(tBackpack.getBbId());
//                tBackpackOperate.setOperateStatus(tBackpack.getBbStatus());
//                tBackpackOperate.setUserId(tBackpack.getUserId());
//                tBackpackOperate.setAuditStatus(tBackpack.getAuditStatus());
//                tBackpackOperate.setCreateTime(DateUtils.getNowDate());
//                tBackpackOperateList.add(tBackpackOperate);

            }
            tBackpackMapper.updateTBackpackStatusBatchVo(tBackpackList);
            /**插入取回记录 */
//            tBackpackOperateMapper.insertTBackpackOperateBatch(tBackpackOperateList);
            return Response.success("正在取回中，请登录steam进行取回操作");
        }else {
            return Response.fail("请刷新页面重试");
        }


    }

    @Override
    @Transactional
    public Response<String> backGiveGoods(GiveGoodsVo giveGoodsVo) {
        if (StringUtils.isEmpty(giveGoodsVo.getGoodsId()) || StringUtils.isEmpty(giveGoodsVo.getUserId())) {
            return Response.fail(Constants.FAILCODE,"参数不能为空！");
        }
        /**无勾选默认为无门槛*/
        if (StringUtils.isEmpty(giveGoodsVo.getRollMkType())){
            giveGoodsVo.setRollMkType(Constants.ROLLMKTYPE0);
        }

        String userId = giveGoodsVo.getUserId();
        TUser tUser = tUserMapper.selectTUserById(userId);

        if (tUser == null || (!tUser.getDelFlag().equals(Constants.SUCCESS))) {
            return Response.fail(Constants.FAILCODE,"用户不存在或已被停用！");
        }

        /**获取加入门槛类型*/
        /**
         * 赠送饰品门槛类型 ROLL房门槛类型 0 无门槛 1 关注门槛 2 充值总额门槛 3 时间段内充值门槛 4 关注门槛+充值总额门槛
         * 5 关注门槛+时间段内充值门槛 6密码 7时间段注册门槛
         */
        /**判断用户是否能加入ROLL房*/
        boolean flag = false;
        String mktype = giveGoodsVo.getRollMkType();
        if (Constants.ROLLMKTYPE0.equals(mktype)) {
            flag = true;
        }
        /**推广用户*/
        TUser tgUser = null;
        if(Constants.ROLLMKTYPE1.equals(mktype) || Constants.ROLLMKTYPE4.equals(mktype) || Constants.ROLLMKTYPE5.equals(mktype)){
            tgUser = tUserMapper.selectTUserById(tUser.getUserPromotersId());
        }
        if (Constants.ROLLMKTYPE1.equals(mktype)) {
            /**判断该用户的推广人的推广码是否为此ROLL的关注推广码*/
            if (StringUtils.isNotEmpty(tUser.getUserPromotersId())){
                if(tgUser != null){
                    if (giveGoodsVo.getRollGzMk().equalsIgnoreCase(tgUser.getUserSelfCode())) {
                        flag = true;
                    }
                }
            }
        }
        if (Constants.ROLLMKTYPE2.equals(mktype)) {
            /**判断该用户的充值总额是否达到加入ROLL房标准*/
            if (tUser.getUserTotalRecharge().compareTo(giveGoodsVo.getRollCzMk()) >= 0) {
                flag = true;
            }
        }
        /**获取用户时间范围内的充值信息*/
        if (Constants.ROLLMKTYPE3.equals(mktype)) {
            /**时间范围内充值门槛*/
            BigDecimal money = tRechargeMapper.czMoneyCountByUserId(userId, giveGoodsVo.getRollStartTime(), giveGoodsVo.getRollEndTime());
            money = money == null ? new BigDecimal(0) : money;
            if (money.compareTo(giveGoodsVo.getRollFwczMk()) >= 0) {
                flag = true;
            }
        }
        if (Constants.ROLLMKTYPE4.equals(mktype)) {
            /**关注门槛+充值总额门槛*/
            if (tgUser != null) {
                if (giveGoodsVo.getRollGzMk().equalsIgnoreCase(tgUser.getUserSelfCode()) && (tUser.getUserTotalRecharge().compareTo(giveGoodsVo.getRollCzMk()) >= 0)) {
                    flag = true;
                }
            }
        }
        if (Constants.ROLLMKTYPE5.equals(mktype)) {
            /**关注门槛+时间范围内充值门槛*/
            BigDecimal money = tRechargeMapper.czMoneyCountByUserId(userId, giveGoodsVo.getRollStartTime(), giveGoodsVo.getRollEndTime());
            money = money == null ? new BigDecimal(0) : money;
            if (tgUser != null) {
                if (giveGoodsVo.getRollGzMk().equalsIgnoreCase(tgUser.getUserSelfCode()) && (money.compareTo(giveGoodsVo.getRollFwczMk()) >= 0)) {
                    flag = true;
                }
            }
        }
        if (Constants.ROLLMKTYPE6.equals(mktype)) {
            /**门槛密码*/
            return Response.fail(Constants.FAILCODE,"无此类型！");
        }
        if(Constants.ROLLMKTYPE7.equals(mktype)){
            /*判断当前用户注册时间是否在注册时间段内*/
            Date rollStartTime = giveGoodsVo.getRollStartTime();
            Date rollEndTime = giveGoodsVo.getRollEndTime();
            Date userCreateTime = tUser.getCreateTime();
            if(rollEndTime != null && rollEndTime != null && userCreateTime != null){
                if(userCreateTime.compareTo(rollStartTime) >= 0 && userCreateTime.compareTo(rollEndTime) < 1){
                    flag = true;
                }
            }
        }

        if (flag){
            TGoods tGoods = tGoodsPoolMapper.selectTGoodsById(giveGoodsVo.getGoodsId());
            tGoods.setCreateTime(DateUtils.getNowDate());
            tGoods.setGoodsChance(new BigDecimal("0.01"));
            tGoods.setGoodsStockStatus("0");
            tGoods.setGoodsBelongingType(Constants.GOOGSBLTYPE7);
            tGoods.setGoodsBelongingId(null);
            tGoods.setGoodsPutnum(1L);
            tGoods.setGoodsStocknum(1L);
            tGoods.setGoodsExprice(tGoods.getGoodsPrice());
            tGoodsMapper.insertTGoods(tGoods);

            /**用户符合领取条件*/
            String bbId = DateUtils.dateTimeNow() + IdUtils.fastUUID().substring(0, 8);
            /**插入背包表*/
            TBackpack backpack = new TBackpack();
            backpack.setBbId(bbId);
            backpack.setUserId(userId);
            backpack.setGoodsId(tGoods.getGoodsId());
            backpack.setGoodsBelongingType(Constants.GOOGSBLTYPE7);
            backpack.setGoodsBelongingId(tGoods.getGoodsBelongingId());
            backpack.setGoodsBelongingName("赠送饰品");
            backpack.setGoodsPrice(tGoods.getGoodsPrice());
            backpack.setGoodsExprice(tGoods.getGoodsExprice());
            backpack.setDelFlag(Constants.SUCCESS);
            backpack.setCreateTime(DateUtils.getNowDate());
            backpack.setGoodsType(tGoods.getGoodsType());
            backpack.setGoodsNum(1);
            backpack.setOpenBeforeBalance(tUser.getUserBalance());
            backpack.setUserPromotersId(tUser.getUserPromotersId());
            backpack.setOpenBoxPrice(new BigDecimal(0));
            backpack.setAuditStatus(Constants.AUDITSTATUS0);
            backpack.setBbGoodsName(tGoods.getGoodsName());
            backpack.setBbGoodsPic(tGoods.getGoodsPic());
            backpack.setBbGoodsGrate(tGoods.getGoodsGrate());
            backpack.setOpenAfterBalance(tUser.getUserBalance());
            tBackpackMapper.insertTBackpack(backpack);


            TBalanceChange balanceChange= new TBalanceChange();
            balanceChange.setUserId(userId);
            balanceChange.setBalanceBefore(tUser.getUserBalance());
            balanceChange.setOperationType(Constants.OPERATIONTYPE18);
            balanceChange.setFrequency(1);
            balanceChange.setFee(BigDecimal.ZERO);
            balanceChange.setCorrespondingid(tGoods.getGoodsId());
            balanceChange.setCreateTime(DateUtils.getNowDate());
            balanceChange.setBalanceAfter(tUser.getUserBalance());
            balanceChange.setSecondCurrencyBefore(tUser.getSecondCurrency());
            balanceChange.setSecondCurrencyAfter(tUser.getSecondCurrency());
            balanceChange.setConsumeValue(BigDecimal.ZERO);
            balanceChange.setProfitPrice(tGoods.getGoodsPrice());
            balanceChange.setCostFee(BigDecimal.ZERO);
            balanceChangeMapper.insertTBalanceChange(balanceChange);

            return Response.success("操作成功");
        }else{
            return Response.fail(Constants.FAILCODE,"该用户不符合条件！");
        }
    }

//    /**
//     * 取消人工发货中待发货和待收货的交易订单
//     * @param orderId
//     * @return
//     */
//    @Override
//    public Response buyerCancel(String orderId) {
//        log.info("取消的交易订单ID：{}",orderId);
//        String result = commonService.buyerCancel(orderId);
//        log.info("ZBT取消订单返回参数：{}",result);
//        JSONObject jsonObject = JSON.parseObject(result);
//        if (jsonObject.getBoolean("success")) {
//            JSONObject dataobj = jsonObject.getJSONObject("data");
//            Long successnum = dataobj.getLong("successNum");
//            if (successnum > 0){
//               return Response.success("交易订单已成功取消");
//            }else {
//                return Response.fail("订单可能已取消，请上zbt确认: "+jsonObject.getString("errorMsg"));
//            }
//        }else {
//            return Response.fail("调取取消订单接口失败："+jsonObject.getString("errorMsg"));
//        }
//    }

    /**
     * 取消悠悠有品订单
     * @param orderId
     * @return
     */
    @Override
    public Response buyerCancel(String bbId) {
        TBackpack tBackpack = tBackpackMapper.selectTBackpackById(bbId);
        if(tBackpack == null || !tBackpack.getBbStatus().equals(Constants.BBSTATUS5)){
            return Response.fail("背包不存在或者背包状态非待发货状态，不可取消订单");
        }
        if(StringUtils.isEmpty(tBackpack.getOrderId())){
            return Response.fail("不存在此订单号，联系管理员确认");
        }

        String body = commonService.buyerCancelYY(tBackpack.getOrderId());
        JSONObject jsonObject = JSON.parseObject(body);
        if (jsonObject.getInteger("code") == 0) {
            JSONObject dataobj = jsonObject.getJSONObject("data");
            Integer result = dataobj.getInteger("result");
            if (result == 1){
                return Response.success("交易订单已成功取消");
            }else if(result == 2) {
                return Response.success("取消订单处理中");
            }else {
                return Response.fail("订单取消失败，请上平台确认");
            }
        }else {
            return Response.fail("调取取消订单接口失败："+jsonObject.getString("msg"));
        }
    }

    @Override
    public List<GoodsBelongingVo> carouselListTop3() {
        String beginCreateTime = DateUtils.getDate() + " 00:00:00";
        List<GoodsBelongingVo> top3List = tBackpackMapper.top3CarouselList(beginCreateTime);
        return top3List;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dealFailed(List<TBackPackVo> list) {
        for (TBackPackVo tBackpack : list) {
            tBackpack.setBbStatus(Constants.BBSTATUS0);
            tBackpack.setAuditStatus(Constants.AUDITSTATUS0);
            tBackpack.setUpdateTime(DateUtils.getNowDate());
            tBackpack.setErrormsg("已回到用户背包");
            tUserMapper.subHistoryRecoveryQuota(tBackpack.getUserId(),tBackpack.getGoodsPrice());
        }
        int row = tBackpackMapper.updateTBackpackStatusBatchErrorVo(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response returnBackPack(String bbId,String userId) {
        TUser tUser = tUserMapper.selectTUserById(userId);
        if (tUser == null || (!tUser.getDelFlag().equals(Constants.SUCCESS))) {
            return Response.fail(Constants.FAILCODE,"用户不存在或已被停用！");
        }
        TBackPackVo tBackpack = tBackpackMapper.selectTBackpackByIdVo(bbId);
        if(tBackpack == null || !tBackpack.getBbStatus().equals(Constants.BBSTATUS4)){
            return Response.fail(Constants.FAILCODE,"不符合退回条件！");
        }
        String lockKey = Constants.RETRIEVEKEY + tBackpack.getBbId();
        String lockTime = DateUtils.getTimeAfter(DateUtils.getNowDate(), 1);
        lockTime = Long.toString(DateUtils.parseDate(lockTime).getTime());
        try {
            boolean lockflag = redisLock.lock(lockKey, lockTime);
            if (!lockflag) {
                return Response.fail(Constants.FAILCODE,"网络延迟，稍后再试");
            }
            List<TBackPackVo> list = new ArrayList<>();
            list.add(tBackpack);
            this.dealFailed(list);
        }finally {
            redisLock.release(lockKey, lockTime);
        }
        return Response.success();
    }
}
